package com.pyl.admin.system.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageInfo;
import com.pyl.admin.core.constant.AdminConst;
import com.pyl.admin.core.enums.ResultEnum;
import com.pyl.admin.core.enums.StatusEnum;
import com.pyl.admin.core.exception.ResultException;
import com.pyl.admin.core.shiro.ShiroUtil;
import com.pyl.admin.system.entity.SysMenu;
import com.pyl.admin.system.entity.SysRole;
import com.pyl.admin.system.entity.SysRoleMenu;
import com.pyl.admin.system.entity.SysUser;
import com.pyl.admin.system.service.SysMenuService;
import com.pyl.admin.system.service.SysRoleMenuService;
import com.pyl.admin.system.service.SysRoleService;
import com.pyl.admin.system.service.SysUserService;
import com.pyl.admin.system.validator.RoleForm;
import com.pyl.core.utils.ResultVoUtil;
import com.pyl.core.vo.ResultVo;

import cn.hutool.core.collection.CollectionUtil;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 灵魂贰婶
 * @since 2019-06-28
 */
@Controller
@RequestMapping("/system/role")
public class SysRoleController {

	@Autowired
	private SysRoleService sysRoleService;

	@Autowired
	private SysMenuService sysMenuService;

	@Autowired
	private SysRoleMenuService sysRoleMenuService;

	@Autowired
	private SysUserService sysUserService;

	/**
	 * 列表页面
	 */
	@GetMapping("/index")
	@RequiresPermissions("/system/role/index")
	public String index(Model model, @RequestParam(required = false, defaultValue = "1") Integer status,
			@RequestParam(required = false) String query) {

		// 获取角色列表
		PageInfo<SysRole> page = sysRoleService.selectRoelList(status, query);
		// 封装数据
		model.addAttribute("list", page.getList());
		model.addAttribute("page", page);
		return "/system/role/index";
	}

	/**
	 * 跳转到添加页面
	 */
	@GetMapping("/add")
	@RequiresPermissions("/system/role/add")
	public String toAdd() {
		return "/system/role/add";
	}

	/**
	 * 跳转到编辑页面
	 */
	@GetMapping("/edit/{id}")
	@RequiresPermissions("/system/role/edit")
	public String toEdit(@PathVariable("id") Long id, Model model) {
		SysRole sysRole = sysRoleService.selectById(id);
		model.addAttribute("role", sysRole);
		return "/system/role/add";
	}

	/**
	 * 保存添加/修改的数据
	 *
	 * @param roleForm 表单验证对象
	 */
	@PostMapping("/save")
	@RequiresPermissions({ "/system/role/add", "/system/role/edit" })
	@ResponseBody
	public ResultVo<?> save(@Validated RoleForm roleForm) {
		// 不允许操作管理员角色数据
		if (roleForm.getId() != null && roleForm.getId().equals(AdminConst.ADMIN_ROLE_ID)
				&& !ShiroUtil.getSubject().getId().equals(AdminConst.ADMIN_ID)) {
			throw new ResultException(ResultEnum.NO_ADMINROLE_AUTH);
		}
		sysRoleService.saveOrUpdate(roleForm);
		return ResultVoUtil.SAVE_SUCCESS;
	}

	/**
	 * 跳转到授权页面
	 */
	@GetMapping("/auth")
	@RequiresPermissions("/system/role/auth")
	public String toAuth(@RequestParam(value = "ids") Long id, Model model) {
		model.addAttribute("id", id);
		return "/system/role/auth";
	}

	/**
	 * 获取权限资源列表
	 */
	@GetMapping("/authList")
	@RequiresPermissions("/system/role/auth")
	@ResponseBody
	public ResultVo<?> authList(@RequestParam(value = "ids") Long id) {
		// 获取指定角色权限资源
		SysRole sysRole = sysRoleService.selectRoleMenuById(id);
		List<SysMenu> authMenus = sysRole.getSysMenus();
		// 获取全部菜单列表
		List<SysMenu> sysMenus = sysMenuService.selectList(new EntityWrapper<SysMenu>()
				.eq("status", Integer.valueOf(StatusEnum.OK.getCode())).orderAsc(Arrays.asList("sort")));
		// 融合两项数据
		for (int i = 0; i < sysMenus.size(); i++) {
			for (int j = 0; j < authMenus.size(); j++) {
				if (authMenus.get(j).getId().equals(sysMenus.get(i).getId())) {
					sysMenus.get(i).setRemark("auth:true");
				}
			}
		}
		return ResultVoUtil.success(sysMenus);
	}

	/**
	 * 保存授权信息
	 */
	@PostMapping("/auth")
	@RequiresPermissions("/system/role/auth")
	@ResponseBody
	public ResultVo<?> auth(@RequestParam(value = "id", required = true) Long id,
			@RequestParam(value = "authId", required = false) List<Long> authIds) {
		// 不允许操作管理员角色数据
		if (id.equals(AdminConst.ADMIN_ROLE_ID) && !ShiroUtil.getSubject().getId().equals(AdminConst.ADMIN_ID)) {
			throw new ResultException(ResultEnum.NO_ADMINROLE_AUTH);
		}
		// 将查询的数据关联起来
		SysRole sysRole = sysRoleService.selectById(id);

		List<SysMenu> sysMenus = null;
		if (CollectionUtil.isNotEmpty(authIds)) {
			sysMenus = sysMenuService.selectBatchIds(authIds);
			// 重置角色权限
			sysRoleMenuService.delete(new EntityWrapper<SysRoleMenu>().eq("role_id", sysRole.getId()));
			List<SysRoleMenu> list = new ArrayList<>();
			for (int i = 0; i < sysMenus.size(); i++) {
				SysRoleMenu sysRoleMenu = new SysRoleMenu();
				sysRoleMenu.setRoleId(sysRole.getId());
				sysRoleMenu.setMenuId(sysMenus.get(i).getId());
				list.add(sysRoleMenu);
			}
			// 保存数据
			sysRoleMenuService.insertBatch(list);
		}

		return ResultVoUtil.SAVE_SUCCESS;
	}

	/**
	 * 跳转到详细页面
	 */
	@GetMapping("/detail/{id}")
	@RequiresPermissions("/system/role/detail")
	public String toDetail(@PathVariable("id") Long id, Model model) {
		SysRole role = sysRoleService.selectById(id);
		model.addAttribute("role", role);
		return "/system/role/detail";
	}

	/**
	 * 跳转到拥有该角色的用户列表页面
	 */
	@GetMapping("/userList/{id}")
	@RequiresPermissions("/system/role/detail")
	public String toUserList(@PathVariable("id") Long id, Model model) {
		List<SysUser> sysUsers = sysUserService.selectLocalUserByRoleId(String.valueOf(id));
		model.addAttribute("list", sysUsers);
		return "/system/role/user_list";
	}

	/**
	 * 设置一条或者多条数据的状态
	 */
	@RequestMapping("/status/{param}")
	@RequiresPermissions("/system/role/status")
	@ResponseBody
	public ResultVo<?> status(@PathVariable("param") String param,
			@RequestParam(value = "ids", required = false) List<Long> idList) {
		// 不能修改超级管理员角色状态
		if (idList.contains(AdminConst.ADMIN_ROLE_ID)) {
			throw new ResultException(ResultEnum.NO_ADMINROLE_STATUS);
		}

		try {
			// 获取状态StatusEnum对象
			StatusEnum statusEnum = StatusEnum.valueOf(param.toUpperCase());
			// 更新状态
			boolean result = sysRoleService.updateStatus(statusEnum, idList);
			return result ? ResultVoUtil.success(statusEnum.getMessage() + "成功")
					: ResultVoUtil.error(statusEnum.getMessage() + "失败，请重新操作");
		} catch (IllegalArgumentException e) {
			throw new ResultException(ResultEnum.STATUS_ERROR);
		}
	}

}
